﻿package com.actionpals.components.controls.calendar
{
    import com.actionpals.components.controls.Calendar;
    import com.actionpals.events.CalendarEvent;
    import com.actionpals.utils.ArrayUtil;
    import com.actionpals.utils.DateUtil;
    
    import flash.display.Sprite;
	
    public class CalendarMonth extends Sprite
    {
		private var calendar:Calendar;
		private var daysOfMonths:Array = new Array( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
		private var firstDay:int;
		private var totalDays:int;
		private var rows:Number = 6;
		private var dayWidth:Number;
		private var dayHeight:Number;
		private var arrayOfDays:Array = new Array();
		
		private var _width:Number;
		private var _height:Number;
		
		public function CalendarMonth( calendar:Calendar, width:Number, height:Number )
		{
			super();
			
			this.calendar = calendar;
			this._width = width;
			this._height = height;
			
			init();
		}
		
		public function drawNow():void
		{
			var dayCount:int = arrayOfDays.length-1;
			for( var i:int=dayCount; i>=0; i-- )
			{
				CalendarDay( arrayOfDays[ i ] ).drawNow();
			}
		}
		
		private function init():void
		{
			firstDay = new Date( calendar.displayedYear, calendar.displayedMonth, 1 ).day;
			totalDays = ( calendar.displayedYear % 4 == 0 && calendar.displayedMonth == 1 ? 29 : daysOfMonths[ calendar.displayedMonth ] );
			dayWidth = ( _width - ( calendar.style.dayHorizontalGap * ( calendar.dayNames.length + 1 ) ) - ( calendar.style.borderThickness * 2 ) ) / calendar.dayNames.length;
			dayHeight = ( _height - ( calendar.style.dayVerticalGap * ( rows + 1 ) ) - ( calendar.style.borderThickness * 2 ) ) / rows;
			
			createDays();
		}
		
		public function createDays():void
		{
			var eventArray:Array = new Array();
			var date:Date;
			var dayOfWeek:Number = firstDay;
            var row:uint = 0;
            
            for( var i:int=0; i<totalDays; i++ )
            {
				date = new Date( calendar.displayedYear, calendar.displayedMonth, ( i + 1 ) );
				eventArray = getDateEvents( date );
				
				var day:CalendarDay = new CalendarDay( date, dayWidth, dayHeight, calendar.showToday, eventArray, calendar.style );
				day.selected = DateUtil.compareDates( calendar.selectedDate, date ) == 0;
				if( calendar.showVisited ) for( var j:int=0; j<calendar.visitedDates.length; j++ ) if( DateUtil.compareDates( calendar.visitedDates[ j ], date ) == 0 ) day.visited = true;
				day.addEventListener( CalendarEvent.DATE_SELECT, onDateSelect );
				
				day.x = dayOfWeek * ( dayWidth + calendar.style.dayHorizontalGap ) + calendar.style.dayHorizontalGap + calendar.style.borderThickness;
				day.y = row * ( dayHeight + calendar.style.dayVerticalGap ) + calendar.style.dayVerticalGap + calendar.style.borderThickness;
				
				addChild( day );
				arrayOfDays.push( day );
				
				dayOfWeek++;
                if( dayOfWeek >= calendar.dayNames.length )
                {
                    dayOfWeek = 0;
                    row++;
                }
            }
			
        }
		
		private function getDateEvents( date:Date ):Array
		{
			var retArray:Array = new Array();
			
			for( var i:uint; i<calendar.events.length; i++ )
			{
				if( dateCompare( date, calendar.events[ i ].startDate ) >= 0 )
				{
					if( dateCompare( date, calendar.events[ i ].endDate ) <= 0 )
					{
						retArray.push( calendar.events[ i ] );
					}
				}
			}
			
			return retArray;
		}
		
		private function dateCompare( date1:Date, date2:Date ):int
		{
			if( date1.getFullYear() > date2.getFullYear() )
			{
				return 1;
			}
			else if( date1.getFullYear() < date2.getFullYear() )
			{
				return -1;
			}
			else
			{
				if( date1.getMonth() > date2.getMonth() )
				{
					return 1;
				}
				else if( date1.getMonth() < date2.getMonth() )
				{
					return -1;
				}
				else
				{
					if( date1.getDate() > date2.getDate() )
					{
						return 1;
					}
					else if( date1.getDate() < date2.getDate() )
					{
						return -1;
					}
					else
					{
						return 0;
					}
				}
			}
		}
		
		
		private function onDateSelect( evt:CalendarEvent ):void
		{
			calendar.selectedDate = DateUtil.compareDates( calendar.selectedDate, evt.date ) != 0 ? evt.date : null;
			if( !ArrayUtil.arrayContainsValue( calendar.visitedDates, evt.date ) ) calendar.visitedDates.push( evt.date );
		}
		
	}
}
